package icraf.carbon.gui.model;

import icraf.carbon.core.Project;
import icraf.carbon.core.Zone.DataType;
import icraf.carbon.gui.LCMatrixTabPanel;
import icraf.carbon.gui.MenuFactory.MenuProperty;
import icraf.carbon.gui.ProjectPanel;
import icraf.carbon.gui.RowHighlight;
import icraf.carbon.model.ModelProject;
import icraf.common.gui.VerticalLabelUI;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.JLabel;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelListener;

public class ModelIterationPanel extends ProjectPanel implements InstantCounter<ModelIterationPanel>{
	

	public class ZoneTabListener implements ChangeListener {

		@Override
		public void stateChanged(ChangeEvent evt) {
			JTabbedPane p = (JTabbedPane) evt.getSource();
			activeZoneTabIndex  = p.getSelectedIndex();
		}

	}
	
	public class IterationTabListener implements ChangeListener {

		@Override
		public void stateChanged(ChangeEvent evt) {
			JTabbedPane p = (JTabbedPane) evt.getSource();
			LCMatrixTabPanel mPanel = (LCMatrixTabPanel) p.getSelectedComponent();
			mPanel.selectZoneTab(activeZoneTabIndex);
		}

	}
	
	private static final long serialVersionUID = 3935329706944049274L;

	private boolean isRowHighlight = false;
	private ModelProject modelProject;
	private RowHighlight rowHighlight;
	private MouseListener rowMouseListener;
	private TableModelListener tableModelListener;
	JTabbedPane tabPanel = new JTabbedPane(JTabbedPane.LEFT);
	private ArrayList<ChangeListener> changeListenerList = new ArrayList<ChangeListener>();
	//TODO: default value?
	private boolean isZoneAreaScale;
	private int activeZoneTabIndex = 0;
	private ZoneTabListener zoneTabListener = new ZoneTabListener();

	private boolean editable = false;
	
	public ModelIterationPanel() {
		super();
		tabPanel.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
		this.setLayout(new BorderLayout());
		this.add(tabPanel);
		JLabel l = new JLabel(MenuProperty.MODEL_PERIOD.getLabel()+ " ");
		l.setFont(new Font("Arial", Font.BOLD, 16));
		l.setOpaque(true);
		l.setBackground(Color.gray);
		l.setForeground(Color.white);
		l.setUI(new VerticalLabelUI());
		l.setHorizontalAlignment(JLabel.RIGHT);
		this.add(l, BorderLayout.WEST);
		
		tabPanel.addChangeListener(new IterationTabListener());
	}

	public void fireTableDataChanged() {
		LCMatrixTabPanel mPanel;
		for (int i = 0; i < tabPanel.getTabCount(); i++) {
			mPanel = (LCMatrixTabPanel) tabPanel.getComponentAt(i);
			mPanel.fireTableDataChanged();
		}
	}

	public ModelProject getModelProject() {
		return modelProject;
	}

	public int getSelectedTabIndex() {
		return tabPanel.getSelectedIndex();
	}

	public JTabbedPane getTabPanel() {
		return tabPanel;
	}

	public void setZoneAreaScale(boolean isZoneAreaScale) {
		this.isZoneAreaScale = isZoneAreaScale;
		LCMatrixTabPanel mPanel;
		for (int i = 0; i < tabPanel.getTabCount(); i++) {
			mPanel = (LCMatrixTabPanel) tabPanel.getComponentAt(i);
			mPanel.setZoneAreaScale(isZoneAreaScale);
		}
	}
	
	public void setSelectUnitArea(boolean b) {
		LCMatrixTabPanel mPanel;
		for (int i = 0; i < tabPanel.getTabCount(); i++) {
			mPanel = (LCMatrixTabPanel) tabPanel.getComponentAt(i);
			mPanel.setSelectUnitArea(b);
		}
	}
	
	public void setAreaScale(boolean b) {
		LCMatrixTabPanel mPanel;
		for (int i = 0; i < tabPanel.getTabCount(); i++) {
			mPanel = (LCMatrixTabPanel) tabPanel.getComponentAt(i);
			mPanel.setAreaScale(b);
		}
	}
	
	public void setCornerSetting(String unitDef, String unitArea, boolean isUnitSelectable) {
		LCMatrixTabPanel mPanel;
		for (int i = 0; i < tabPanel.getTabCount(); i++) {
			mPanel = (LCMatrixTabPanel) tabPanel.getComponentAt(i);
			mPanel.setCornerSetting( unitDef,  unitArea, isUnitSelectable);
		}
	}

	public void setEditable(boolean b) {
		editable  = b;
		LCMatrixTabPanel mPanel;
		for (int i = 0; i < tabPanel.getTabCount(); i++) {
			mPanel = (LCMatrixTabPanel) tabPanel.getComponentAt(i);
			mPanel.setEditable(b);
		}
	}

	public void setModelProject(ModelProject modelProject, DataType dataType, Object attributs) {
		this.modelProject = modelProject;
//		int period = 0;
		int n = -1;
		if(modelProject != null) {
//			period = (int)modelProject.getMainProject().getDurationTime();
			n = modelProject.getIterationCount();
		}
		
		while (tabPanel.getTabCount() > n + 1) {
			tabPanel.remove(tabPanel.getTabCount() - 1);
		}
		LCMatrixTabPanel mPanel;
		for (int i = 0; i < n + 1; i++) {
			if (i < tabPanel.getTabCount()) {
				mPanel = (LCMatrixTabPanel) tabPanel.getComponentAt(i);
				tabPanel.setTitleAt(i, Integer.toString(i));
			} else {
				mPanel = new LCMatrixTabPanel();
				tabPanel.addTab(Integer.toString(i), mPanel);

				if (rowMouseListener != null) {
					mPanel.setRowMouseListener(rowMouseListener);
				}
				if (tableModelListener != null)
					mPanel.setTableModelListener(tableModelListener);
				
				mPanel.addZoneTabListener(zoneTabListener);
				for(ChangeListener l: changeListenerList) {
					mPanel.addZoneTabListener(l);
				}
			}
			tabPanel.setEnabledAt(i, true);
			mPanel.setProject(modelProject.getSimulatedProject(i));
			mPanel.setDataType(dataType, attributs);
			
			if (isRowHighlight) {
				mPanel.setRowHighlight(isRowHighlight, rowHighlight);
			}
			mPanel.setEditable(editable);
			mPanel.setZoneAreaScale(isZoneAreaScale);
		}

	}

	public void setRowHighlight(boolean b, RowHighlight h) {
		isRowHighlight = b;
		rowHighlight = h;
		LCMatrixTabPanel mPanel;
		for (int i = 0; i < tabPanel.getTabCount(); i++) {
			mPanel = (LCMatrixTabPanel) tabPanel.getComponentAt(i);
			mPanel.setRowHighlight(b, h);
		}

	}

	public void setRowMouseListener(MouseListener rowMouseListener) {
		this.rowMouseListener = rowMouseListener;
	}

	public void setTableModelListener(TableModelListener tableModelListener) {
		this.tableModelListener = tableModelListener;
	}
	
	public void addZoneTabListener(ChangeListener l) {
		changeListenerList.add(l);
		LCMatrixTabPanel mPanel;
		for (int i = 0; i < tabPanel.getTabCount(); i++) {
			mPanel = (LCMatrixTabPanel) tabPanel.getComponentAt(i);
			mPanel.addZoneTabListener(l);
		}
	}
	
	public void selectZoneTab(int idx) {
		LCMatrixTabPanel mPanel;
		for (int i = 0; i < tabPanel.getTabCount(); i++) {
			mPanel = (LCMatrixTabPanel) tabPanel.getComponentAt(i);
			mPanel.selectZoneTab(idx);
		}
	}

	@Override
	public void setProject(Project project, DataType t, Object attributes) {
		setModelProject(project.getModelProject(), t, attributes);
	}
	
	public void setDataType(DataType t, Object attributes) {
		setModelProject(getModelProject(), t, attributes);
	}

	@Override
	public ModelIterationPanel createInstant() {
		return new ModelIterationPanel();
	}
	
	private Component topComponent;
	public void setTopComponent(Component c) {
		if(topComponent != null)
			this.remove(topComponent);
		this.add(c, BorderLayout.NORTH);
		topComponent = c;
	}

}